package com.xzakota.minesweeper;

import com.xzakota.minesweeper.log.XLogger;
import com.xzakota.minesweeper.model.entity.RoomBean;
import com.xzakota.minesweeper.msg.BaseMsg;
import com.xzakota.minesweeper.msg.ChatMsg;
import com.xzakota.minesweeper.msg.MsgCode;

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * 多人对战房间
 *
 * @author Xzakota
 */
public class RoomAtServer extends RoomBean {
    // 房间内的用户集
    public List<ConnectedUserHandler> users = new ArrayList<>();

    public RoomAtServer(int num) {
        super(num);
    }

    /**
     * 用户进入房间
     *
     * @param handler 用户
     * @return 是否进入成功
     */
    public int addUser(ConnectedUserHandler handler) {
        if (roomCurrentOnline + 1 <= roomMaxOnline) {
            users.add(handler);
            roomCurrentOnline++;

            ChatMsg msg = new ChatMsg();
            msg.data = new Object[] {null, "欢迎 " + handler.currentUser.username + " 进入房间"};
            sendMsgToOther(handler, msg);

            return MsgCode.BASE_SUCCESS;
        } else {
            return MsgCode.ENTER_ROOM_IS_FULL;
        }
    }

    /**
     * 用户退出房间
     *
     * @param handler 用户
     * @return 是否退出成功
     */
    public int removeUser(ConnectedUserHandler handler) {
        if (roomCurrentOnline - 1 >= 0) {
            users.remove(handler);
            roomCurrentOnline--;

            ChatMsg msg = new ChatMsg();
            msg.data = new Object[] {null, handler.currentUser.username + " 离开房间"};
            sendMsgToOther(handler, msg);
        }

        return MsgCode.BASE_SUCCESS;
    }

    /**
     * 发送消息给房间里的其他用户
     *
     * @param self 需要排除自己
     * @param msg  消息
     */
    public void sendMsgToOther(ConnectedUserHandler self, BaseMsg msg) {
        try {
            for (ConnectedUserHandler now : users) {
                if (self != now && !now.socket.isClosed()) {
                    OutputStream os = now.socket.getOutputStream();
                    ObjectOutputStream oos = new ObjectOutputStream(os);
                    oos.writeObject(msg);
                    oos.flush();
                }
            }
        } catch (IOException e) {
            XLogger.error("发送消息给房间里的其他用户失败", e);
        }
    }

    /**
     * 发送消息给房间里的所有用户
     *
     * @param msg 消息
     */
    public void sendMsgToAll(BaseMsg msg) {
        try {
            for (ConnectedUserHandler now : users) {
                if (!now.socket.isClosed()) {
                    OutputStream os = now.socket.getOutputStream();
                    ObjectOutputStream oos = new ObjectOutputStream(os);
                    oos.writeObject(msg);
                    oos.flush();
                }
            }
        } catch (IOException e) {
            XLogger.error("发送消息给房间里的所有用户失败", e);
        }
    }
}
